﻿using System;
using System.Web;
using System.Web.Mvc;
using UncleBobWebService.Models;
using System.Collections.Generic;


namespace UncleBobApplicantWebService.Controllers
{
    public class ApplicantApplyController : Controller
    {
        //
        // NextQuestion() : ActionResult
        // ------------------------------------------------------------------------
        // NextQuestion will determine whether the next question is MultipleChoice
        // or Extended, and will redirect to the appropriate handler accordingly.
        //
        public ActionResult NextQuestion()
        {
            ApplicationQuestions questions = Session["ApplicationQuestions"] as ApplicationQuestions;

            if (questions.Questions[questions.CurrentQuestion] is MultipleChoiceQuestion)
            {
                return RedirectToAction("MultipleChoiceQuestion", "ApplicantApply");
            }
            else
            {
                return RedirectToAction("ExtendedQuestion", "ApplicantApply");
            }
        }

        //
        // EvaluateApplication() : ActionResult
        // ------------------------------------------------------------------------
        // EvaluateAction will process flow of control when all Questions have been
        // answered. It will evaluate all of the applicant's responses to the the
        // questions and determine whether the MC questions are all correct. If not,
        // it will refuse submission. Otherwise, it will submit the application to 
        // the database.
        //
        public ActionResult EvaluateApplication()
        {
            ApplicationQuestions questions = Session["ApplicationQuestions"] as ApplicationQuestions;
            
            bool isAccepted = true;
            bool isFinished = false;
            
            // iterate over all questions for processing
            for (int i = 0; i < questions.Questions.Count && !isFinished; ++i)
            {
                // if you encounter a MultipleChoiceQuestion, we want to process the Applicant's answers
                if (questions.Questions[i] is MultipleChoiceQuestion)
                {
                    MultipleChoiceQuestion q = questions.Questions[i] as MultipleChoiceQuestion;

                    foreach (KeyValuePair<int, Answer> answer in q.PossibleAnswers)
                    {
                        // Determine whether the Applicant's selected Answer matches the
                        // correct Answer. If not, change the isAccepted flag to false
                        // and break out of the loop.
                        if (answer.Value.IsSelected != answer.Value.IsCorrect)
                        {
                            isAccepted = false;
                            isFinished = true;
                            break;
                        }
                    }
                }
            }

            //
            // Generate the appropriate message after determining whether the application
            // has been accepted or not.
            //
            string resultMessage = string.Empty;

            if (!isAccepted)
                resultMessage = "We're sorry. Your application cannot be submitted at this time.";
            else
                resultMessage = "Thank you! Your application has been submitted successfully.";

            ViewData.Model = resultMessage;
            return View();
        }

        //
        // MultipleChoiceQuestion() : ActionResult
        // ------------------------------------------------------------------------
        // The handler will pass the current question to the MultipleChoiceQuestion
        // view.
        //
        public ActionResult MultipleChoiceQuestion()
        {
            ApplicationQuestions questions = Session["ApplicationQuestions"] as ApplicationQuestions;
            MultipleChoiceQuestion question = questions.Questions[questions.CurrentQuestion] as MultipleChoiceQuestion;
            question.RuntimeCount = questions.CurrentQuestion;

            return View(question);
        }

        //
        // ExtendedQuestion() : ActionResult
        // ------------------------------------------------------------------------
        // The handler will pass the current question to the ExtendedQuestion view.
        //
        public ActionResult ExtendedQuestion()
        {
            ApplicationQuestions questions = Session["ApplicationQuestions"] as ApplicationQuestions;
            ExtendedQuestion question = questions.Questions[questions.CurrentQuestion] as ExtendedQuestion;
            question.RuntimeCount = questions.CurrentQuestion;

            return View(question);
        }

        //
        // FormAction() : ActionResult
        // ------------------------------------------------------------------------
        // FormAction will process the FormCollection returned by the View and then
        // redirect to the NextQuestion if there are more questions. Otherwise,  
        // redirect to EvaluateApplication method.
        //
        public ActionResult FormAction(FormCollection collection)
        {
            // Go back to applicant main if user is finished
            if (collection["applicantmain"] != null)
            {
                return RedirectToAction("MainMenu", "ApplicantMainMenu");
            }

            ApplicationQuestions questions = Session["ApplicationQuestions"] as ApplicationQuestions;

            // If the current question is MultipleChoice, process the applicant's answer to the question
            if (questions.Questions[questions.CurrentQuestion] is MultipleChoiceQuestion)
            {
                ProcessAnswers(questions.Questions[questions.CurrentQuestion]
                    as MultipleChoiceQuestion, collection);
            }

            // Otherwise, it is an ExtendedQuestion. Store their response.
            else
            {
                ExtendedQuestion question = questions.Questions[questions.CurrentQuestion] as ExtendedQuestion;
                question.Response = collection["answer"];
            }

            // Continue processing questions if there are any remaining...
            if (questions.CurrentQuestion < (questions.TotalQuestions - 1))
            {
                if (collection["next"] != null) 
                    ++questions.CurrentQuestion;
                else 
                    --questions.CurrentQuestion;

                return RedirectToAction("NextQuestion", "ApplicantApply");
            }

            // Otherwise, evaluate the applicant's Application
            else
            {
                return RedirectToAction("EvaluateApplication", "ApplicantApply");
            }
        }

        //
        // ProcessAnswers() : void
        // ---------------------------------------------------------------------
        // Determine which question the applicant marked as the correct response
        // and save for later processing.
        //
        private void ProcessAnswers(MultipleChoiceQuestion question, FormCollection collection)
        {
            int count = 0;

            // Iterate over each item in the sorted dictionary until you find the
            // answer which the user has selected.
            foreach (KeyValuePair<int, Answer> answer in question.PossibleAnswers)
            {
                string index = Convert.ToString(count);

                if (collection["answer"] == index)
                {
                    answer.Value.IsSelected = true;
                    break;
                }

                ++count;
            }
        }
    }
}
